<?php

namespace Module\Admin;

use Manager\Options as Manager;
use W3\Html;

!defined('W3_ROOT_DIR') AND exit;

/**
 * 基本设置组件
 *
 * @author edikud
 * @date 2022/10/22
 * @copyright Copyright (c) 2022 W3 (http://www.mcooo.com)
 * @license GNU General Public License 2.0
 */
class General extends Manager
{
    /**
     * 初始化
     *
     * @access protected
     * @return void
     */
    protected function init()
    {
		# 定义变量默认数据
        $this->parameter([

			# 设置主体
			'main' => 'admin.general',	
			
		], true);	
		
        # 必须为管理员以上权限
        $this->auth->check('admin');

	}
	
    /**
     * 绑定动作
     *
     * @access public
     * @return void
     */
    public function action()
    {
		$this->on(!$this->request->action || $this->request->is('action=index'))->index();
		$this->on($this->request->isPost() && (!$this->request->action || $this->request->is('action=index')))->update();
    }

    public function index()
    {
		/** 输出内容 */
		$this->layout->set($this->form(), 'body');
		
		$this->view();
    }

    /**
     * 获取语言列表
     * 
     * @access private
     * @return array
     */
    public function getLangs()
    {
        $files = glob(W3_ROOT_DIR . 'system/lang/*.php');
        $langs = [];
        if (!empty($files)) {
            foreach ($files as $file) 
			{
                list($name) = explode('.', basename($file));
                $langs[$name] = __($name);
            }
            ksort($langs);
        }
        return $langs;
    }

    /**
     * 检查是否在语言列表中 
     * 
     * @param mixed $lang 
     * @access public
     * @return bool
     */
    public function checkLang($lang)
    {
        $langs = $this->getLangs();
        return isset($langs[$lang]);
    }

    /**
     * 输出表单结构
     *
     * @access public
     * @return Form
     */
    public function form()
    {
        /** 构建表格 */
		$form = Html::form();

        /** 站点名称 */
        $title = Html::text('title', $this->config->title)
		    ->label(__('站点名称'))
		    ->description(__('站点的名称将显示在网页的标题处.'))
		    ->addRule('required', __('请填写站点名称'))
			->addRule('xss', __('请不要在站点名称中使用特殊字符'));

        $form->addInput($title);

        /** 站点地址 */

        $siteUrl = Html::text('siteUrl', $this->config->siteUrl)
			->label(__('站点地址'))
		    ->description(__('站点地址主要用于生成内容的永久链接.'))
		    ->addRule('required', __('请填写站点地址'))
			->addRule('xss', __('请填写一个合法的URL地址'));

	    $this->config->siteUrl != $this->config->rootUrl 
			&& $siteUrl->message(__('当前地址 <strong>%s</strong> 与上述设定值不一致', [$this->config->rootUrl]));	
				
        $form->addInput($siteUrl);

        /** 站点描述 */
        $description = Html::text('description', $this->config->description)
		    ->label(__('站点描述'))
		    ->description(__('站点描述将显示在网页代码的头部.'))
			->addRule('xss', __('请不要在站点描述中使用特殊字符'));

		$form->addInput($description);
		
        /** 关键词 */
        $keywords = Html::text('keywords', $this->config->keywords)
		    ->label(__('关键词'))
		    ->description(__('请以半角逗号 "," 分割多个关键字.'))
			->addRule('xss', __('请不要在关键词中使用特殊字符'));

        $form->addInput($keywords);
		
        /** 注册 */
        $allowRegister = Html::radio('allowRegister', ['0' => __('不允许'), '1' => __('允许')], $this->config->allowRegister)
		    ->label(__('是否允许注册'))
		    ->description(__('允许访问者注册到你的网站, 默认的注册用户不享有任何写入权限.'));

        $form->addInput($allowRegister);

        $langs = $this->getLangs();
        if (count($langs) > 1) {
            $lang = Html::select('lang', $langs, $this->config->lang)
		        ->label(__('语言'))
				->addRule([$this, 'checkLang'], __('所选择的语言包不存在'));

            $form->addInput($lang);
        }
		
        /** 时区 */
        $timezoneList = [
            "0"         => __('格林威治(子午线)标准时间 (GMT)'),
            "3600"      => __('中欧标准时间 阿姆斯特丹,荷兰,法国 (GMT +1)'),
            "7200"      => __('东欧标准时间 布加勒斯特,塞浦路斯,希腊 (GMT +2)'),
            "10800"     => __('莫斯科时间 伊拉克,埃塞俄比亚,马达加斯加 (GMT +3)'),
            "14400"     => __('第比利斯时间 阿曼,毛里塔尼亚,留尼汪岛 (GMT +4)'),
            "18000"     => __('新德里时间 巴基斯坦,马尔代夫 (GMT +5)'),
            "21600"     => __('科伦坡时间 孟加拉 (GMT +6)'),
            "25200"     => __('曼谷雅加达 柬埔寨,苏门答腊,老挝 (GMT +7)'),
            "28800"     => __('北京时间 香港,新加坡,越南 (GMT +8)'),
            "32400"     => __('东京平壤时间 西伊里安,摩鹿加群岛 (GMT +9)'),
            "36000"     => __('悉尼关岛时间 塔斯马尼亚岛,新几内亚 (GMT +10)'),
            "39600"     => __('所罗门群岛 库页岛 (GMT +11)'),
            "43200"     => __('惠灵顿时间 新西兰,斐济群岛 (GMT +12)'),
            "-3600"     => __('佛德尔群岛 亚速尔群岛,葡属几内亚 (GMT -1)'),
            "-7200"     => __('大西洋中部时间 格陵兰 (GMT -2)'),
            "-10800"    => __('布宜诺斯艾利斯 乌拉圭,法属圭亚那 (GMT -3)'),
            "-14400"    => __('智利巴西 委内瑞拉,玻利维亚 (GMT -4)'),
            "-18000"    => __('纽约渥太华 古巴,哥伦比亚,牙买加 (GMT -5)'),
            "-21600"    => __('墨西哥城时间 洪都拉斯,危地马拉,哥斯达黎加 (GMT -6)'),
            "-25200"    => __('美国丹佛时间 (GMT -7)'),
            "-28800"    => __('美国旧金山时间 (GMT -8)'),
            "-32400"    => __('阿拉斯加时间 (GMT -9)'),
            "-36000"    => __('夏威夷群岛 (GMT -10)'),
            "-39600"    => __('东萨摩亚群岛 (GMT -11)'),
            "-43200"    => __('艾尼威托克岛 (GMT -12)')
        ];

        $timezone = Html::select('timezone', $timezoneList, $this->config->timezone)
		    ->label(__('时区'));
		
        $form->addInput($timezone);
		
        /** 扩展名 */
        $attachmentTypesOptionsResult = (NULL != trim($this->config->attachmentTypes)) ? 
            array_map('trim', explode(',', $this->config->attachmentTypes)) : [];
        $attachmentTypesOptionsValue = [];
        
        if (in_array('@image@', $attachmentTypesOptionsResult)) {
            $attachmentTypesOptionsValue[] = '@image@';
        }
        
        if (in_array('@media@', $attachmentTypesOptionsResult)) {
            $attachmentTypesOptionsValue[] = '@media@';
        }
        
        if (in_array('@doc@', $attachmentTypesOptionsResult)) {
            $attachmentTypesOptionsValue[] = '@doc@';
        }
        
        $attachmentTypesOther = array_diff($attachmentTypesOptionsResult, $attachmentTypesOptionsValue);
        $attachmentTypesOtherValue = '';
        if (!empty($attachmentTypesOther)) {
            $attachmentTypesOptionsValue[] = '@other@';
            $attachmentTypesOtherValue = implode(',', $attachmentTypesOther);
        }
        
        $attachmentTypesOptions = [
            '@image@'    =>  __('图片文件') . ' <code>(gif jpg jpeg png tiff bmp)</code>',
            '@media@'    =>  __('多媒体文件') . ' <code>(mp3 wmv wma rmvb rm avi flv)</code>',
            '@doc@'      =>  __('常用档案文件') . ' <code>(txt doc docx xls xlsx ppt pptx zip rar pdf)</code>',
            '@other@'    =>  __('其他格式 %s', [' <input type="text" class="d-inline-block form-control form-control-sm" style="width:220px;" name="attachmentTypesOther" value="' . htmlspecialchars($attachmentTypesOtherValue) . '" />']),
        ];
        
        $attachmentTypes = Html::checkbox('attachmentTypes', $attachmentTypesOptions, $attachmentTypesOptionsValue)
		    ->label(__('允许上传的文件类型'))
		    ->description(__('用逗号 "," 将后缀名隔开, 例如: %s', ['<code>cpp, h, mak</code>']));

        $form->addInput($attachmentTypes);
		
        /** 提交按钮 */
        $submit = Html::submit(__('保存设置'));
        $form->set($submit);
		
        return $form;
    }

    /**
     * 过滤掉可执行的后缀名
     *
     * @param string $ext
     * @return boolean
     */
    public function removeShell($ext)
    {
        return !preg_match("/^(php|php4|php5|sh|asp|jsp|rb|py|pl|dll|exe|bat)$/i", $ext);
    }

    /**
     * 执行更新动作
     *
     * @access public
     * @return void
     */
    public function update()
    {
		$form = $this->form();
	
		/** 验证格式 */
        if ($form->validate()) {
            $this->goBack();
        }

        $settings = $this->request->from(array_keys($form->getInputs()));
        $settings['attachmentTypes'] = $this->request->getArray('attachmentTypes');
        $settings['siteUrl'] = rtrim($this->request->siteUrl, '/');

        $attachmentTypes = [];
        if ($this->isEnableByCheckbox($settings['attachmentTypes'], '@image@')) {
            $attachmentTypes[] = '@image@';
        }
        
        if ($this->isEnableByCheckbox($settings['attachmentTypes'], '@media@')) {
            $attachmentTypes[] = '@media@';
        }
        
        if ($this->isEnableByCheckbox($settings['attachmentTypes'], '@doc@')) {
            $attachmentTypes[] = '@doc@';
        }
        
        $attachmentTypesOther = $this->request->filter('trim', 'strtolower')->attachmentTypesOther;
        if ($this->isEnableByCheckbox($settings['attachmentTypes'], '@other@') && !empty($attachmentTypesOther)) {
            $types = implode(',', array_filter(array_map('trim',
                explode(',', $attachmentTypesOther)), [$this, 'removeShell']));

            if (!empty($types)) {
                $attachmentTypes[] = $types;
            }
        }
        
        $settings['attachmentTypes'] = implode(',', $attachmentTypes);

        foreach ($settings as $name => $value) 
		{
            $this->updateOptions($name, $value);
        }
		
        $this->notice(__("设置已经保存"));
		
		$this->goBack();
    }

    /**
     * 以checkbox选项判断是否某个值被启用
     *
     * @access protected
     * @param mixed $settings 选项集合
     * @param string $name 选项名称
     * @return integer
     */
    protected function isEnableByCheckbox($settings, $name)
    {
        return is_array($settings) && in_array($name, $settings) ? 1 : 0;
    }

}
